﻿package kizzo.utils
{
	import flash.events.ProgressEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	//import org.flashdevelop.utils.FlashConnect;
	import flash.errors.*;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.Bitmap;
	import flash.display.PixelSnapping;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.net.URLRequest;	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import kizzo.utils.CustomEvent;
	
		
	public class Library extends EventDispatcher
	{		
		private var loader_array:Array;
		private var load_state_array:Array;
		private var load_info:Array;
		private var bmp_array:Array;
		private var bmp_data_array:Array;
		
		private var items_to_load:uint;
		private var total_items:uint;
		private var items_started:uint;
		
		//private var bytes_loaded:Number;
		private var bytes_total:Number;		
		
		static public const LOAD_ITEM:String = "loadItem";
		static public const LOAD_ALL:String = "loadAll";
		static public const LOAD_PROGRESS:String = "loadProgress";
		
		function Library()	
		{
			this.loader_array = [];
			this.load_state_array = [];
			
			this.bmp_array = [];
			this.bmp_data_array = [];
			
			this.bytes_total = 0;
			
			this.items_to_load = 0;
			this.total_items = 0;
			this.items_started = 0;			
		}
				
		public function load(url:String, name:String):void
		{		
			if (this.loader_array[name] == null)
			{
				this.loader_array[name] = new Loader();
				this.loader_array[name].name = name;
				this.loader_array[name].load(new URLRequest(url));
				this.loader_array[name].contentLoaderInfo.addEventListener(Event.COMPLETE, copy_bmp_data);				
				
				this.load_state_array[name] = {started:false, bytes_loaded:0, bytes_total:0, contentLoaderInfo:this.loader_array[name].contentLoaderInfo};
				
				this.bmp_data_array[name] = null;
				this.bmp_array[name] = new Bitmap(this.bmp_data_array[name]);
				
				this.items_to_load++;
				this.total_items++;
				this.loader_array[name].contentLoaderInfo.addEventListener(Event.OPEN, item_start_handler);
				this.loader_array[name].contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, item_progress_handler);
			}
			else
			{				
				//throw new Error("Duplication of library material name. Material " + name + " not added to library.");				
			}
		}
		
		private function item_start_handler(evt:Event):void
		{
			this.bytes_total += evt.target.bytesTotal;
			//FlashConnect.trace(String(evt.target.loader));
			//this.items_started++;						
		}
		
		
		private function item_progress_handler(evt:Event):void
		{
			dispatchEvent(new Event(LOAD_PROGRESS));
			
			for (var name:String in this.load_state_array)
			{				
				if (this.load_state_array[name].contentLoaderInfo == evt.target)
				{
					if (this.load_state_array[name].started == false)
					{
						this.items_started++;
						this.load_state_array[name].started = true;
						this.bytes_total += evt.target.bytesTotal;
					}
				}
			}
		}
		
		public function getBytesLoaded():Number
		{
			var bytes_loaded:Number = 0;
			
			for(var names:String in this.loader_array)
				bytes_loaded += this.loader_array[names].contentLoaderInfo.bytesLoaded;
				
			return bytes_loaded;			
		}
		
		public function getBytesTotal():Number
		{
			if (this.items_started<this.total_items)
				return Number.POSITIVE_INFINITY;
			else
				return this.bytes_total;		
		}		
		
		public function load_from_xml():void
		{
			
		}
		
		private function copy_bmp_data(event:Event):void
		{					
			var name:String = event.target.loader.name;				
			this.bmp_data_array[name] = new BitmapData(event.target.loader.width, event.target.loader.height, true, 0x00000000);	
			
			this.bmp_array[name].bitmapData = this.bmp_data_array[name];	
			this.bmp_array[name].smoothing = true;
			this.bmp_array[name].pixelSnapping = PixelSnapping.NEVER;
			
			this.bmp_data_array[name].draw(event.target.loader);
			
			var evt_load_item:CustomEvent = new CustomEvent(LOAD_ITEM,{name:name});			
			dispatchEvent(evt_load_item);			
			
			this.items_to_load--;
			//trace(this.items_to_load);
			
			if (this.items_to_load == 0)
			{
				var evt_load_all:Event = new Event(LOAD_ALL);				
				dispatchEvent(evt_load_all);
			}
		}
		
		public function isLoaded(name:String):Boolean
		{
			return this.bmp_data_array[name] as Boolean;
		}
		
		public function getBitmap(name:String):Bitmap
		{			
			return (this.bmp_array[name]);
		}
		
		public function getBitmapClone(name:String):Bitmap		
		{
			return new Bitmap(this.bmp_data_array[name].clone(), PixelSnapping.NEVER, true);
		}
		
		public function getColorTransformedBitmapClone(name:String, color_transform:ColorTransform):Bitmap		
		{
			var temp_bmp:Bitmap = new Bitmap(this.bmp_data_array[name], PixelSnapping.NEVER, true);
			var final_bmp_data:BitmapData = new BitmapData(temp_bmp.width, temp_bmp.height, true, 0x00000000);
			final_bmp_data.draw(temp_bmp, new Matrix(), color_transform);
			return new Bitmap(final_bmp_data, PixelSnapping.NEVER, true);			
		}
		
		public function getBitmapData(name:String):BitmapData
		{			
			return (this.bmp_data_array[name]);			
		}
		
		public function getLoader(name:String):Loader
		{
			return (this.loader_array[name]);			
		}
		
		public function itemIsAdded(name:String):Boolean
		{
			return Boolean(this.loader_array[name]);
		}
		
		public function getDisplayObject(name:String):DisplayObject
		{
			return loader_array[name];
		}
	}
	

}